﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Xoohoo.Extensions;
using Xoohoo.Infrastructure;
using Xoohoo.Models;
using Xoohoo.Models.ViewModels;
using Xoohoo.Modules.Admin.Extensions;
using Xoohoo.Modules.Admin.Models;
using Xoohoo.Modules.Admin.Services;
using Xoohoo.Services;
using Xoohoo.Utilities.Security;

namespace Xoohoo.Modules.Admin.Controllers
{
    public class AdminController : Controller, IModuleSubMenu
    {
        private readonly IFormsAuthentication _formsAuthentication;
        private readonly IUserService _userService;
        private readonly IAdminUserService _adminUserService;
        private readonly IModuleRegistry _modulesLoaded;
        private readonly IBulletinService _bulletinService;
        private readonly XoohooContext _context;

        public AdminController(IFormsAuthentication formsAuthentication
            , IUserService userService
            , IAdminUserService adminUserService
            , IModuleRegistry modulesLoaded
            , IBulletinService bulletinService
            , XoohooContext context)
        {
            this._formsAuthentication = formsAuthentication;
            this._userService = userService;
            this._adminUserService = adminUserService;
            this._modulesLoaded = modulesLoaded;
            this._bulletinService = bulletinService;
            this._context = context;
        }

        #region IModuleSubMenu Members

        public XoohooViewModelItem<ModuleSubMenuItemList> SubMenu()
        {
            //快捷菜单在后期要做成可以自定义的
            var sm = new ModuleSubMenuItemList("快捷菜单") { 
                new ModuleSubMenuItemSingle{ Title="快捷菜单", MenuLevel=1}
                ,new ModuleSubMenuItemSingle{ Title="管理首页", ContentRouteName="Admin.Welcome", MenuLevel=2,Permission="后台修改资料"}
                ,new ModuleSubMenuItemSingle{ Title="修改资料", ContentRouteName="Admin.ChangeProfile", MenuLevel=2,Permission="后台修改资料"}
                ,new ModuleSubMenuItemSingle{ Title="修改密码", ContentRouteName="Admin.ChangePassword", MenuLevel=2,Permission="后台修改密码"}
                ,new ModuleSubMenuItemSingle{ Title="退出登录", ContentRouteName="Admin.SignOut", MenuLevel=2}
            };
            var bulletin = _bulletinService.GetItem();

            if (bulletin != null && bulletin.IsShow)
            {
                var subMenuItem = new ModuleSubMenuItemSingle { Title = "系统公告({0})".FormatWith(bulletin.PublishDate.ToString("yyyy-MM-dd")), ContentRouteName = "Admin.Bulletin", MenuLevel = 2 };
                sm.Insert(2, subMenuItem);
            }
            sm.RemoveByPermission(_context.User);
            return new XoohooViewModelItem<ModuleSubMenuItemList>(sm);
        }

        #endregion

        public object SignIn()
        {
            return new XoohooViewModelItem<UserSignInInput>();
        }
        [HttpPost]
        public object SignIn(UserSignInInput userSignInInput)
        {
            bool isAjaxRequest = Request.IsAjaxRequest();

            //输入校验
            //验证码、用户名、密码空校验，用户名、密码长度校验
            if (!TryValidateModel(userSignInInput))
            {
                if (isAjaxRequest)
                    return Json(new { Result = this.ModelState.First().Value }, JsonRequestBehavior.AllowGet);
                else
                    return new XoohooViewModelItem<UserSignInInput>(userSignInInput);
            }

            if (Session["ValidateCode"] == null)
            {
                string message = "验证码已到期，请返回刷新页面或刷新验证码！";
                if (isAjaxRequest)
                    return Json(new { Result = message }, JsonRequestBehavior.AllowGet);
                else
                {
                    PromptViewModel prompt = new PromptViewModel("登录提示");
                    prompt.Message.Add(message);

                    XoohooViewModelItem<PromptViewModel> xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
                    return View("Prompt",xvm);
                }
            }

            if (String.Compare(Session["ValidateCode"].ToString(), userSignInInput.ValidateCode, true) != 0)
            {
                string message = "请输入正确的验证码！";
                if (isAjaxRequest)
                    return Json(new { Result = message }, JsonRequestBehavior.AllowGet);
                else
                {
                    PromptViewModel prompt = new PromptViewModel("登录提示");
                    prompt.Message.Add(message);

                    XoohooViewModelItem<PromptViewModel> xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
                    return View("Prompt",xvm);
                }
            }

            //登陆成功与否都清理验证码，以防止暴力测试密码
            Session.Remove("ValidateCode");

            if (_userService.SignIn(() => _userService.GetNormalUser(userSignInInput.Username, userSignInInput.Password)
                , (u) =>
                {
                    _formsAuthentication.SetAuthCookie("{0}|{1}".FormatWith("Admin",u.Name), false);
                }))
            {
                if (isAjaxRequest)
                    return Json(new { Result = String.Empty }, JsonRequestBehavior.AllowGet);
                else
                    return RedirectToAction("Index");
            }
            else
            {
                string message = "登陆失败，用户名或密码错误。";
                if (isAjaxRequest)
                    return Json(new { Result = message }, JsonRequestBehavior.AllowGet);
                else
                {
                    List<string> messages = new List<string>();
                    messages.Add(message);
                    messages.Add("请尝试再次登录，如果仍然提示该错误，请与管理员联系。");
                    PromptViewModel prompt = new PromptViewModel("登录提示", messages, "返回重新登录", null);

                    XoohooViewModelItem<PromptViewModel> xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
                    return View("Prompt",xvm);

                }
            }
        }

        public XoohooViewModelItem<ModuleMenuItemList> Index()
        {
            //在PermissionAuthorizationFilter中已经进行了操作权限校验
            //（配合路由设置中的Perssion值）
            //这里可以通过访问权限获取菜单项

            //获取主菜单
            var itemList = new ModuleMenuItemList();
            var modules = _modulesLoaded.GetModules<IModuleMetaData>();
            foreach (IModuleMetaData module in modules)
            {
                var items = module.GetModuleMenus();
                if (items.IsNullOrEmpty()) continue;

                foreach (var item in items)
                {
                    if(item.Permission.IsNullOrWhiteSpace())
                    {
                        itemList.Add(item);
                        continue;
                    }
                    var perArray = item.Permission.Split('|');
                    foreach (var it in perArray)
                    {
                        if (_context.User.HasPermission(it))
                        {
                            itemList.Add(item);
                            break;
                        }
                    }
                }
            }
            var xvm = new XoohooViewModelItem<ModuleMenuItemList>(itemList);

            Bulletin bulletin = _bulletinService.GetItem();
            if (bulletin != null && bulletin.IsShow)
                ViewBag.Welcome = "Admin.Bulletin";
            else
                ViewBag.Welcome = "Admin.Welcome";
            return xvm;
        }
               
        public object ChangeProfile()
        {
            User user = _context.User.Cast<User>();
            if (user == null) return null;

            UserChangeProfileInput input = new UserChangeProfileInput { 
             DisplayName = user.DisplayName,
             Email = user.Email
            };
            return new XoohooViewModelItem<UserChangeProfileInput>(input);
        }

        [HttpPost]
        public object ChangeProfile(UserChangeProfileInput input)
        {
            //构建 Prompt 以及返回对象
            var prompt = new PromptViewModel("修改资料");
            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
            if (!TryValidateModel(input))
            {
                //prompt.AddModelErrors(ModelState);
                //return View("Prompt", xvm);
                return new XoohooViewModelItem<UserChangeProfileInput>(input);
            }

            User user = _context.User.Cast<User>();
            if (user == null) return null;

            ModelResult modelResult = _adminUserService.ChangeProfile(user, input);

            if (modelResult.IsValid)
            {
                prompt.AddMessage("修改资料成功！");
            }
            else
            {
                prompt.AddModelErrors(modelResult.Errors);
            }

            return View("Prompt",xvm);
        }

        public XoohooViewModel ChangePassword()
        {
            return new XoohooViewModelItem<UserChangePasswordInput>();
        }
        [HttpPost]
        public object ChangePassword(UserChangePasswordInput input)
        {
            //构建 Prompt 以及返回对象
            var prompt = new PromptViewModel("修改密码");
            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
            if (!TryValidateModel(input))
            {
                //prompt.AddModelErrors(ModelState);
                //return View("Prompt", xvm);
                return new XoohooViewModelItem<UserChangePasswordInput>(input);
            }

            //判断当前密码是否输入正确
            User user = _context.User.Cast<User>();
            if (user == null) return null;

            ModelResult modelResult = _adminUserService.ChangePassword(user,input);
            if (modelResult.IsValid)
            {
                prompt.AddMessage("修改密码成功！");
            }
            else
            {
                prompt.AddModelErrors(modelResult.Errors);
            }

            return View("Prompt",xvm);
        }

        public XoohooViewModel Welcome()
        {
            return new XoohooViewModel();
        }

        public object Bulletin()
        {
            Bulletin bulletin = _bulletinService.GetItem();

            if (bulletin == null || !bulletin.IsShow) return null;

            return new XoohooViewModelItem<Bulletin>(bulletin);
        }

        public ActionResult SignOut()
        {
            _userService.SignOut();
            _formsAuthentication.SignOut();
            return RedirectToAction("SignIn");
        }

        public ActionResult GetValidateCode()
        {
            string code;
            ValidateCodeCreater vCode = new ValidateCodeCreater(5, out code);
            Session["ValidateCode"] = code;
            byte[] bytes = vCode.CreateValidateGraphic();
            return File(bytes, @"image/jpeg");
        }
    }

}
